using System;
using System.ComponentModel;
using System.IO.Ports;
using System.Threading;

namespace VexedLogic.X10
{
	public class Firecracker : IDisposable
	{
		private const string Header = "1101010110101010";

		private const string Footer = "10101101";

		private const string BrightCmdSignal = "10001000";

		private const string DimCmdSignal = "10011000";

		private const string LowerDevSignal = "0000";

		private const string UpperDevSignal = "0100";

		private const int Delay = 30;

		private readonly SerialPort comPort;

		private bool disposed;

		private readonly string[,] mBinaryCommandCode;

		private readonly string[] mBinaryHouseCode;

		public Firecracker(int comPortNum)
		{
			string[,] strArrays = new string[16, 2];
			strArrays[0, 0] = "00000000";
			strArrays[0, 1] = "00100000";
			strArrays[1, 0] = "00010000";
			strArrays[1, 1] = "00110000";
			strArrays[2, 0] = "00001000";
			strArrays[2, 1] = "00101000";
			strArrays[3, 0] = "00011000";
			strArrays[3, 1] = "00111000";
			strArrays[4, 0] = "01000000";
			strArrays[4, 1] = "01100000";
			strArrays[5, 0] = "01010000";
			strArrays[5, 1] = "01110000";
			strArrays[6, 0] = "01001000";
			strArrays[6, 1] = "01101000";
			strArrays[7, 0] = "01011000";
			strArrays[7, 1] = "01111000";
			strArrays[8, 0] = "00000000";
			strArrays[8, 1] = "00100000";
			strArrays[9, 0] = "00010000";
			strArrays[9, 1] = "00110000";
			strArrays[10, 0] = "00001000";
			strArrays[10, 1] = "00101000";
			strArrays[11, 0] = "00011000";
			strArrays[11, 1] = "00111000";
			strArrays[12, 0] = "01000000";
			strArrays[12, 1] = "01100000";
			strArrays[13, 0] = "01010000";
			strArrays[13, 1] = "01110000";
			strArrays[14, 0] = "01001000";
			strArrays[14, 1] = "01101000";
			strArrays[15, 0] = "01011000";
			strArrays[15, 1] = "01111000";
			this.mBinaryCommandCode = strArrays;
			string[] strArrays1 = new string[] { "0110", "0111", "0100", "0101", "1000", "1001", "1010", "1011", "1110", "1111", "1100", "1101", "0000", "0001", "0010", "0011" };
			this.mBinaryHouseCode = strArrays1;

			this.comPort = new SerialPort(string.Concat("COM", comPortNum));
			this.comPort.BaudRate = 9600;
			this.comPort.DataBits = 8;
			this.comPort.StopBits = StopBits.One;
			this.comPort.Parity = Parity.None;
			this.comPort.ReadTimeout = 1000;
			this.comPort.WriteTimeout = 1000;
		}

		protected virtual void Dispose(bool disposing)
		{
			if (!this.disposed)
			{
				if (disposing && this.comPort != null)
				{
					this.comPort.Dispose();
				}
				this.disposed = true;
			}
		}

		public void Dispose()
		{
			this.Dispose(true);
			GC.SuppressFinalize(this);
		}

		private string GetBinaryCommandCode(int deviceCode, Firecracker.BinaryCommandCodes codeIndex)
		{
			return this.mBinaryCommandCode[deviceCode - 1, Convert.ToInt32(codeIndex)];
		}

		private string GetBinaryGroupCode(int deviceCode)
		{
			if (deviceCode <= 8)
			{
				return "0000";
			}
			return "0100";
		}

		private string GetBinaryHouseCode(char houseCode)
		{
			houseCode = Convert.ToChar(houseCode.ToString().ToLower());
			return this.mBinaryHouseCode[houseCode - (char)Convert.ToInt32('a')];
		}

		public bool SendCommand(X10Command command)
		{
			return this.SendCommand(command.HouseCode, command.DeviceCode, command.Command);
		}

		public bool SendCommand(char houseCode, int deviceCode, Firecracker.Commands cmd)
		{
			string str = string.Concat("1101010110101010", this.GetBinaryHouseCode(houseCode), this.GetBinaryGroupCode(deviceCode));
			string str1 = cmd.ToString();
			string str2 = str1;
			if (str1 != null)
			{
				if (str2 == "On")
				{
					str = string.Concat(str, this.GetBinaryCommandCode(deviceCode, Firecracker.BinaryCommandCodes.TurnOnIndex));
				}
				else if (str2 == "Off")
				{
					str = string.Concat(str, this.GetBinaryCommandCode(deviceCode, Firecracker.BinaryCommandCodes.TurnOffIndex));
				}
				else if (str2 == "Bright")
				{
					str = string.Concat(str, "10001000");
				}
				else if (str2 == "Dim")
				{
					str = string.Concat(str, "10011000");
				}
			}
			str = string.Concat(str, "10101101");
			this.comPort.Open();
			this.comPort.DtrEnable = false;
			this.comPort.RtsEnable = false;
			Thread.Sleep(30);
			this.comPort.DtrEnable = true;
			this.comPort.RtsEnable = true;
			Thread.Sleep(30);
			for (int i = 0; i < str.Length; i++)
			{
				if (Convert.ToInt32(str.Substring(i, 1)) != 0)
				{
					this.comPort.RtsEnable = true;
					this.comPort.DtrEnable = false;
				}
				else
				{
					this.comPort.DtrEnable = true;
					this.comPort.RtsEnable = false;
				}
				Thread.Sleep(30);
				this.comPort.RtsEnable = true;
				this.comPort.DtrEnable = true;
				Thread.Sleep(30);
			}
			this.comPort.Close();
			return true;
		}

		private enum BinaryCommandCodes
		{
			TurnOnIndex,
			TurnOffIndex
		}

		public enum Commands
		{
			On,
			Off,
			Bright,
			Dim
		}
	}
}